package com.css.economy.evaluate.service.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.lang.UUID;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.css.casualties.entity.GridDestoryDetails;
import com.css.casualties.entity.RyswModel4Data;
import com.css.casualties.service.GridDestoryDetailsService;
import com.css.casualties.service.RyswModel4DataService;
import com.css.config.QueueConfig;
import com.css.config.ThreadPoolConfig;
import com.css.datasourceSwitch.MessageDataSourceSwitch;
import com.css.economy.evaluate.entity.BuildingLossMatrix;
import com.css.economy.evaluate.entity.EconomyBuildingPrice;
import com.css.economy.evaluate.entity.EconomyEvaluate;
import com.css.economy.evaluate.entity.EconomyModel;
import com.css.economy.evaluate.mapper.EconomyEvaluateMapper;
import com.css.economy.evaluate.service.BuildingLossMatrixService;
import com.css.economy.evaluate.service.EconomyBuildingPriceService;
import com.css.economy.evaluate.service.EconomyEvaluateService;
import com.css.economy.evaluate.service.EconomyModelService;
import com.css.entity.DataHouseBrickwork;
import com.css.entity.DataHouseQita;
import com.css.entity.DataHouseRebar;
import com.css.entity.DataHousedanceng;
import com.css.influence.entity.MessageLog.service.MessageLogService;
import com.css.influence.entity.SettingSeismicInfluenceflied;
import com.css.influence.vo.ToEvaluateVO;
import com.css.service.*;
import com.google.common.collect.HashBasedTable;
import com.google.common.collect.Table;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.MessageProperties;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author Dbj
 * @date 2024年09月24日  10:52
 */
@Service
@Slf4j
public class EconomyEvaluateServiceImpl extends ServiceImpl<EconomyEvaluateMapper, EconomyEvaluate> implements EconomyEvaluateService {

    @Resource
    DataHouseDancengService dataHouseDancengService;
    @Resource
    DataHouseQitaService dataHouseQitaService;
    @Resource
    DataHouseRebarService dataHouseRebarService;
    @Resource
    DataHouseRebarRasterService dataHouseRebarRasterService;
    @Resource
    DataHouseBrickworkService dataHouseBrickworkService;
    @Resource
    RyswModel4DataService ryswModel4DataService;
    @Resource
    EconomyBuildingPriceService economyBuildingPriceService;
    @Resource
    GridDestoryDetailsService gridDestoryDetailsService;
    @Resource
    EconomyModelService economyModelService;
    @Resource
    MessageLogService messageLogService ;
    @Resource
    BuildingLossMatrixService buildingLossMatrixService;
    private static final Map<String, Integer> retryMap = new ConcurrentHashMap<>();
    //失败重试次数
    @Value("${spring.rabbitmq.failedRetry}")
    private Integer failedRetry;
    ThreadPoolExecutor executor = ThreadPoolConfig.exeBizThreadPoolExecutor;

    @Resource
    RabbitTemplate rabbitTemplate;

//    @RabbitListener(queues = QueueConfig.QUEUE_CASULATIES_TO_ECONOMY, ackMode = "MANUAL")
//    @RabbitHandler
//    @DSTransactional
//    public void evaluate(Map<String,Object> map, Channel channel, Message message) throws IOException {
//        CompletableFuture completableFuture = CompletableFuture.runAsync(()->{
//            log.info("开始执行经济损失计算");
//            try {
//                channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
//            } catch (IOException e) {
//                e.printStackTrace();
//            }
//            //地震事件id
//            String earthQuakeId = (String)map.get("earthQuakeId");
//            Integer earthType = (Integer)map.get("earthType");
//            Boolean publish = (Boolean) map.get("publish");
//            log.error("地震id"+earthQuakeId+"-- 评估经济损失"+"|| 开始。>> 参数:"+JSON.toJSONString(map));
//            String influenceVersion = "";
//            // 切换到省份数据源
//            String dataSourceKey = (String) map.get("dataSource");
//            //影响场版本
//            if(ObjectUtils.isNotEmpty(map.get("influenceVersion")) || map.get("influenceVersion")!=null){
//                try{
//                    //影响场版本不 null
//                    influenceVersion = JSONObject.parseObject(map.get("influenceVersion").toString(),String.class);
//                    DynamicDataSourceContextHolder.push(dataSourceKey);
//                    //获取人员伤亡模型3计算时得到的每个结构类型各烈度下不同破坏程度的建筑物面积
//                    List<GridDestoryDetails> list = gridDestoryDetailsService.getAll(earthQuakeId,influenceVersion);
//                    if(ObjectUtils.isNotEmpty(list) && list.size()>0){
//                        //获取经济损失模型
//                        EconomyModel economyModel = economyModelService.getOne(null);
//                        //获取建筑物损失比矩阵
//                        List<BuildingLossMatrix> matrixList = buildingLossMatrixService.list(null);
//                        Map<String, BuildingLossMatrix> matrixMap = matrixList.stream().collect(Collectors.toMap(BuildingLossMatrix::getStructureType, Function.identity()));
//                        Map<String,List<EconomyBuildingPrice>> priceMap = new HashMap<>();
//                        //key是烈度 v是该烈度下的建筑物经济损失
//                        Table<String,String,BigDecimal> intensityTable = HashBasedTable.create();
//                        // 建筑物经济损失 = 各烈度不同类建筑物在不同破坏等级下的破坏面积*建筑物每平方米造价*不同类建筑物在不同破坏等级下的损失比*评估调整参数/10000 之和
//                        for (GridDestoryDetails gridDestoryDetails : list) {
//                            //获取建筑物造价数据
//                            List<EconomyBuildingPrice> priceList = null;
//                            if(!priceMap.containsKey(gridDestoryDetails.getGeom())){
//                                //根据空间数据匹配建筑物造价数据
//                                priceList = economyBuildingPriceService.getBuildingPriceByGeom(gridDestoryDetails.getGeomText());
//                                priceMap.put(gridDestoryDetails.getGeom(),priceList);
//                            }else{
//                                priceList = priceMap.get(gridDestoryDetails.getGeom());
//                            }
//                            EconomyBuildingPrice price = null;
//                            if(priceList.size()>0){
//                                price = priceList.get(0);
//                            }
//                            if(price == null){
//                                continue;
//                            }
//                            assert price != null;
//                            String structureType = gridDestoryDetails.getStructureType();
//                            BigDecimal total = BigDecimal.ZERO;
//                            if("1".equals(structureType)){
//                                //total是钢混结构在某一烈度下的不同破坏程度下的建筑物结构经济损失
//                                total = getStructureLoss(gridDestoryDetails,matrixMap,structureType,BigDecimal.valueOf(price.getGanghunRatio()));
//                            }else  if("2".equals(structureType)){
//                                //total是多层砌体在某一烈度下的不同破坏程度下的建筑物结构经济损失
//                                total = getStructureLoss(gridDestoryDetails,matrixMap,structureType,BigDecimal.valueOf(price.getQitiRatio()));
//                            }else  if("3".equals(structureType)){
//                                //total是单层在某一烈度下的不同破坏程度下的建筑物结构经济损失
//                                total = getStructureLoss(gridDestoryDetails,matrixMap,structureType,BigDecimal.valueOf(price.getDangcengRatio()));
//                            }else  if("4".equals(structureType)){
//                                //total是其他结构在某一烈度下的不同破坏程度下的建筑物结构经济损失
//                                total = getStructureLoss(gridDestoryDetails,matrixMap,structureType,BigDecimal.valueOf(price.getQitaRatio()));
//                            }
//                            total = total.multiply(BigDecimal.valueOf(economyModel.getAdjustRatio())).divide(BigDecimal.valueOf(10000),8, RoundingMode.HALF_DOWN);
//                            if(intensityTable.contains(gridDestoryDetails.getIntensity(),gridDestoryDetails.getGeom())){
//                                BigDecimal val ;
//                                try{
//                                    val = intensityTable.get(gridDestoryDetails.getIntensity(),gridDestoryDetails.getGeom());
//                                    val = val.add(total);
//                                    intensityTable.put(gridDestoryDetails.getIntensity(),gridDestoryDetails.getGeom(),val);
//                                }catch (Exception e){
//                                    e.printStackTrace();
//                                }
//
//                            }else{
//                                intensityTable.put(gridDestoryDetails.getIntensity(),gridDestoryDetails.getGeom(),total);
//                            }
//                        }
//                        List<EconomyEvaluate> resultList = new ArrayList<>();
//                        Collection<BigDecimal> values = intensityTable.values();
//                        if(ObjectUtils.isNotEmpty(values) && values.size()>0){
//                            String finalInfluenceVersion = influenceVersion;
//                            intensityTable.rowMap().forEach((k, v)->{
//                                //k是烈度  <烈度的空间数据，建筑物经济损失>
//                                EconomyEvaluate economyEvaluate = new EconomyEvaluate();
//                                economyEvaluate.setId(UUID.randomUUID().toString().replace("-",""))
//                                        .setEarthQuakeId(earthQuakeId).setInfluenceVersion(finalInfluenceVersion).setIntensity(k).setOperateTime(new Date());
//                                v.forEach((k1,v1)->{
//                                    economyEvaluate.setGeom(k1).setStructureLoss(v1).setLifeLoss(BigDecimal.valueOf(economyModel.getLifeRatio()).multiply(v1)).setOtherLoss(BigDecimal.valueOf(economyModel.getOtherRatio()).multiply(v1));
//                                });
//                                resultList.add(economyEvaluate);
//                            });
//                        }
//
//                        log.error("地震id"+earthQuakeId+"-- 评估经济损失"+"|| 成功。>> 参数:"+ JSON.toJSONString(map));
//                        if(resultList.size()>0){
//                            saveBatch(resultList);
//                            try{
//                                //删除人员伤亡处保存的给计算经济损失使用的中间数据
//                                LambdaQueryWrapper<GridDestoryDetails> removeLam = new LambdaQueryWrapper();
//                                removeLam.eq(GridDestoryDetails::getEarthQuakeId,earthQuakeId).eq(GridDestoryDetails::getInfluenceVersion,influenceVersion);
//                                gridDestoryDetailsService.remove(removeLam);
//                            }catch (Exception e){
//                                e.printStackTrace();
//                            }
//                        }
//
//                    }
//                }catch (Exception e){
//                    e.printStackTrace();
//                    String msgId = earthQuakeId;
//                    int retryCount = retryMap.getOrDefault(msgId, 0);
//                    log.error("{},--评估经济损失||失败,处理消息时发生错误:{},即将开始第{}次消息重试...",msgId,e.getMessage(),retryCount + 1, e);
//                    if (retryCount >= failedRetry - 1) {
//                        log.error("{},---评估经济损失||失败,消息将被拒绝，>>参数:{}",msgId,JSON.toJSONString(map));
//                        // 拒绝消息，并且不重新入队
//                        try {
//                            channel.basicReject(message.getMessageProperties().getDeliveryTag(), false);
//                        } catch (IOException ex) {
//                            ex.printStackTrace();
//                        }
//                        retryMap.remove(msgId);
//                    } else {
//                        // 重新发送消息到队列
//                        try {
//                            channel.basicPublish(message.getMessageProperties().getReceivedExchange(),
//                                    message.getMessageProperties().getReceivedRoutingKey(),
//                                    MessageProperties.MINIMAL_PERSISTENT_BASIC,
//                                    JSON.toJSONBytes(map));
//                        } catch (IOException ex) {
//                            ex.printStackTrace();
//                        }
//                        retryMap.put(msgId, retryCount + 1);
//                        log.error("地震id"+earthQuakeId+"-- 评估经济损失"+"|| 失败。>> 参数:"+ JSON.toJSONString(map));
//                    }
//                }finally {
//                    try {
//                        channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
//                    } catch (IOException e) {
//                        e.printStackTrace();
//                    }
//                    MessageDataSourceSwitch.clearDataSource();
//                    //发送消息给报告
//                    sendMsgToReport(earthQuakeId,earthType,dataSourceKey,publish,influenceVersion);
//                }
//            }
//            if(ObjectUtils.isEmpty(map.get("influenceVersion")) || map.get("influenceVersion")==null){
//                //发送消息给报告
//                sendMsgToReport(earthQuakeId,earthType,dataSourceKey,publish,influenceVersion);
//                MessageDataSourceSwitch.clearDataSource();
//            }
//            log.info("经济损失计算完成");
//        },executor);
//
//    }

    private Map<Integer,String> getIntensityMap(){
        Map<Integer,String> map = new HashMap<>();
        map.put(6,"Ⅵ");
        map.put(7,"Ⅶ");
        map.put(8,"Ⅷ");
        map.put(9,"Ⅸ");
        map.put(10,"Ⅹ");
        map.put(11,"Ⅺ");
        map.put(12,"Ⅻ");
        return map;
    }

    private String formatDate(String inputDate){
        // 定义原始日期格式
        DateTimeFormatter inputFormatter = DateTimeFormatter.ofPattern(
                "EEE MMM dd HH:mm:ss z yyyy", Locale.ENGLISH);

        // 解析输入字符串为 LocalDateTime
        LocalDateTime localDateTime = LocalDateTime.parse(inputDate, inputFormatter);

        // 定义目标日期格式
        DateTimeFormatter outputFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

        // 格式化日期为目标格式
        return  localDateTime.format(outputFormatter);
    }

    @RabbitListener(queues = QueueConfig.QUEUE_CASULATIES_TO_ECONOMY, ackMode = "MANUAL")
    @RabbitHandler
    @DSTransactional
    public void evaluate(ToEvaluateVO vo, Channel channel, Message message) throws IOException {
        CompletableFuture completableFuture = CompletableFuture.runAsync(()->{
            log.info("开始执行经济损失计算");
            try {
                channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
            } catch (IOException e) {
                e.printStackTrace();
            }
            //地震事件id
            //地震事件id
            String earthQuakeId = vo.getEarthQuakeId();
            //地震类型
            Integer earthType = vo.getEarthType();
            //地震类型
            Boolean publish = vo.getPublish();
            log.error("地震id"+earthQuakeId+"-- 评估经济损失"+"|| 开始。>> 参数:"+JSON.toJSONString(vo));
            // 切换到省份数据源
            String dataSourceKey = vo.getDataSource();
            //影响场版本
            String influenceVersion = formatDate(vo.getInfluenceVersion().toString());
            //影响场版本
            if(ObjectUtils.isNotEmpty(influenceVersion) || influenceVersion!=null){
                // 切换到省份数据源
                DynamicDataSourceContextHolder.push(dataSourceKey);
                //影响场烈度和对应空间数据集合
                List<ToEvaluateVO.Influence> influenceList = vo.getInfluenceList();
                if(influenceList.size()>0 && influenceVersion!=null) {
                    //获取经济损失模型
                    EconomyModel economyModel = economyModelService.getOne(null);
                    //获取建筑物损失比矩阵
                    List<BuildingLossMatrix> matrixList = buildingLossMatrixService.list(null);
                    Map<String, BuildingLossMatrix> matrixMap = matrixList.stream().collect(Collectors.toMap(BuildingLossMatrix::getStructureType, Function.identity()));
                    Map<Integer, ToEvaluateVO.Influence> intensityMap = influenceList.stream().collect(Collectors.toMap(ToEvaluateVO.Influence::getIntensity, Function.identity()));
                    //实际影响场的最大烈度
                    int maxIntensity = influenceList.stream().mapToInt(ToEvaluateVO.Influence::getIntensity).max().getAsInt();
                    List<EconomyEvaluate> resultList = new ArrayList<>();
                    try{
                        for(int i=6;i<=maxIntensity;i++) {
                            BigDecimal finalTotal = BigDecimal.ZERO;
                            ToEvaluateVO.Influence influence = intensityMap.get(i);
                            if (ObjectUtils.isNotEmpty(influence)) {
                                //根据影响场烈度的空间数据查询易损性数据 模型数据使用的是震级所在的省的数据
                                List<RyswModel4Data> ryswModel4DataList = ryswModel4DataService.getIntersectYsx(influence.getGeom(), influence.getCode(), getIntensityMap().get(i));
                                if (ObjectUtils.isNotEmpty(ryswModel4DataList) && ryswModel4DataList.size() > 0) {
                                    // 一个烈度圈可能与多个易损性数据相交7烈度的一半圈和一批易损性相交，另外半圈可能和另外的一批易损性数据相交
                                    Map<String, List<RyswModel4Data>> pidMap = ryswModel4DataList.stream().collect(Collectors.groupingBy(RyswModel4Data::getIntersectGeom));
                                    Iterator<Map.Entry<String, List<RyswModel4Data>>> iterator = pidMap.entrySet().iterator();
                                    while (iterator.hasNext()) {
                                        Map.Entry<String, List<RyswModel4Data>> next = iterator.next();
                                        List<RyswModel4Data> v = next.getValue();
                                        for (RyswModel4Data ryswModel4Data : v) {
                                            //根据空间数据匹配建筑物造价数据
                                            List<EconomyBuildingPrice> priceList = economyBuildingPriceService.getBuildingPriceByGeom(ryswModel4Data.getIntersectGeom());
                                            for (EconomyBuildingPrice price : priceList) {
                                                if ("1".equals(ryswModel4Data.getStructureType())) {
                                                    //钢混结构
                                                    List<DataHouseRebar> rebarList = dataHouseRebarService.getByGeom(price.getGeomText(), "4490");
                                                    if (ObjectUtils.isNotEmpty(rebarList) && rebarList.size() > 0) {
                                                        BigDecimal area = rebarList.get(0).getHouse();
                                                        if(area.compareTo(BigDecimal.ZERO)==0){
                                                            finalTotal = finalTotal.add(BigDecimal.ZERO);
                                                        }else{
                                                            //获取钢混结构在这个烈度下的不同破坏程度的面积
                                                            //基本完好的
                                                            BigDecimal basicArea = ryswModel4Data.getBasic().multiply(area);
                                                            //轻微破坏的
                                                            BigDecimal slightArea = ryswModel4Data.getSlight().multiply(area);
                                                            //轻微破坏的
                                                            BigDecimal midArea = ryswModel4Data.getMid().multiply(area);
                                                            //轻微破坏的
                                                            BigDecimal seriousArea = ryswModel4Data.getSerious().multiply(area);
                                                            //轻微破坏的
                                                            BigDecimal destoryArea = ryswModel4Data.getDestory().multiply(area);
                                                            //total是多层砌体在某一烈度下的不同破坏程度下的建筑物结构经济损失
                                                            BigDecimal total = BigDecimal.ZERO;
                                                            //钢混 基本完好
                                                            BigDecimal basic = basicArea.multiply(BigDecimal.valueOf(matrixMap.get(ryswModel4Data.getStructureType()).getBasic()));
                                                            total = total.add(basic.multiply(BigDecimal.valueOf(price.getGanghunRatio())));
                                                            //轻微破坏
                                                            BigDecimal slight = slightArea.multiply(BigDecimal.valueOf(matrixMap.get(ryswModel4Data.getStructureType()).getSlight()));
                                                            total = total.add(slight.multiply(BigDecimal.valueOf(price.getGanghunRatio())));
                                                            //中等破坏
                                                            BigDecimal mid = midArea.multiply(BigDecimal.valueOf(matrixMap.get(ryswModel4Data.getStructureType()).getMid()));
                                                            total = total.add(mid.multiply(BigDecimal.valueOf(price.getGanghunRatio())));
                                                            //严重破坏
                                                            BigDecimal serious = seriousArea.multiply(BigDecimal.valueOf(matrixMap.get(ryswModel4Data.getStructureType()).getSerious()));
                                                            total = total.add(serious.multiply(BigDecimal.valueOf(price.getGanghunRatio())));
                                                            //毁坏
                                                            BigDecimal destory = destoryArea.multiply(BigDecimal.valueOf(matrixMap.get(ryswModel4Data.getStructureType()).getDestory()));
                                                            total = total.add(destory.multiply(BigDecimal.valueOf(price.getGanghunRatio())));
                                                            finalTotal = finalTotal.add(total);
                                                        }

                                                    }

                                                }
                                                if ("2".equals(ryswModel4Data.getStructureType())) {
                                                    //多层砌体
                                                    List<DataHouseBrickwork> bwList = dataHouseBrickworkService.getByGeom(ryswModel4Data.getIntersectGeom(), ryswModel4Data.getCode());
                                                    if (ObjectUtils.isNotEmpty(bwList) && bwList.size() > 0) {
                                                        BigDecimal area = bwList.get(0).getHouse();
                                                        if(area.compareTo(BigDecimal.ZERO)==0){
                                                            finalTotal = finalTotal.add(BigDecimal.ZERO);
                                                        }else{
                                                            //获取钢混结构在这个烈度下的不同破坏程度的面积
                                                            //基本完好的
                                                            BigDecimal basicArea = ryswModel4Data.getBasic().multiply(area);
                                                            //轻微破坏的
                                                            BigDecimal slightArea = ryswModel4Data.getSlight().multiply(area);
                                                            //轻微破坏的
                                                            BigDecimal midArea = ryswModel4Data.getMid().multiply(area);
                                                            //轻微破坏的
                                                            BigDecimal seriousArea = ryswModel4Data.getSerious().multiply(area);
                                                            //轻微破坏的
                                                            BigDecimal destoryArea = ryswModel4Data.getDestory().multiply(area);
                                                            //total是多层砌体在某一烈度下的不同破坏程度下的建筑物结构经济损失
                                                            BigDecimal total = BigDecimal.ZERO;
                                                            //钢混 基本完好
                                                            BigDecimal basic = basicArea.multiply(BigDecimal.valueOf(matrixMap.get(ryswModel4Data.getStructureType()).getBasic()));
                                                            total = total.add(basic.multiply(BigDecimal.valueOf(price.getQitiRatio())));
                                                            //轻微破坏
                                                            BigDecimal slight = slightArea.multiply(BigDecimal.valueOf(matrixMap.get(ryswModel4Data.getStructureType()).getSlight()));
                                                            total = total.add(slight.multiply(BigDecimal.valueOf(price.getQitiRatio())));
                                                            //中等破坏
                                                            BigDecimal mid = midArea.multiply(BigDecimal.valueOf(matrixMap.get(ryswModel4Data.getStructureType()).getMid()));
                                                            total = total.add(mid.multiply(BigDecimal.valueOf(price.getQitiRatio())));
                                                            //严重破坏
                                                            BigDecimal serious = seriousArea.multiply(BigDecimal.valueOf(matrixMap.get(ryswModel4Data.getStructureType()).getSerious()));
                                                            total = total.add(serious.multiply(BigDecimal.valueOf(price.getQitiRatio())));
                                                            //毁坏
                                                            BigDecimal destory = destoryArea.multiply(BigDecimal.valueOf(matrixMap.get(ryswModel4Data.getStructureType()).getDestory()));
                                                            total = total.add(destory.multiply(BigDecimal.valueOf(price.getQitiRatio())));
                                                            finalTotal = finalTotal.add(total);
                                                        }

                                                    }
                                                }
                                                if ("3".equals(ryswModel4Data.getStructureType())) {
                                                    //单层
                                                    List<DataHousedanceng> dancengList = dataHouseDancengService.getByGeom(ryswModel4Data.getIntersectGeom(), ryswModel4Data.getCode());
                                                    if (ObjectUtils.isNotEmpty(dancengList) && dancengList.size() > 0) {
                                                        BigDecimal area = dancengList.get(0).getHouse();
                                                        if(area.compareTo(BigDecimal.ZERO)==0){
                                                            finalTotal = finalTotal.add(BigDecimal.ZERO);
                                                        }else{
                                                            //获取钢混结构在这个烈度下的不同破坏程度的面积
                                                            //基本完好的
                                                            BigDecimal basicArea = ryswModel4Data.getBasic().multiply(area);
                                                            //轻微破坏的
                                                            BigDecimal slightArea = ryswModel4Data.getSlight().multiply(area);
                                                            //轻微破坏的
                                                            BigDecimal midArea = ryswModel4Data.getMid().multiply(area);
                                                            //轻微破坏的
                                                            BigDecimal seriousArea = ryswModel4Data.getSerious().multiply(area);
                                                            //轻微破坏的
                                                            BigDecimal destoryArea = ryswModel4Data.getDestory().multiply(area);
                                                            //total是多层砌体在某一烈度下的不同破坏程度下的建筑物结构经济损失
                                                            BigDecimal total = BigDecimal.ZERO;
                                                            //钢混 基本完好
                                                            BigDecimal basic = basicArea.multiply(BigDecimal.valueOf(matrixMap.get(ryswModel4Data.getStructureType()).getBasic()));
                                                            total = total.add(basic.multiply(BigDecimal.valueOf(price.getDangcengRatio())));
                                                            //轻微破坏
                                                            BigDecimal slight = slightArea.multiply(BigDecimal.valueOf(matrixMap.get(ryswModel4Data.getStructureType()).getSlight()));
                                                            total = total.add(slight.multiply(BigDecimal.valueOf(price.getDangcengRatio())));
                                                            //中等破坏
                                                            BigDecimal mid = midArea.multiply(BigDecimal.valueOf(matrixMap.get(ryswModel4Data.getStructureType()).getMid()));
                                                            total = total.add(mid.multiply(BigDecimal.valueOf(price.getDangcengRatio())));
                                                            //严重破坏
                                                            BigDecimal serious = seriousArea.multiply(BigDecimal.valueOf(matrixMap.get(ryswModel4Data.getStructureType()).getSerious()));
                                                            total = total.add(serious.multiply(BigDecimal.valueOf(price.getDangcengRatio())));
                                                            //毁坏
                                                            BigDecimal destory = destoryArea.multiply(BigDecimal.valueOf(matrixMap.get(ryswModel4Data.getStructureType()).getDestory()));
                                                            total = total.add(destory.multiply(BigDecimal.valueOf(price.getDangcengRatio())));
                                                            finalTotal = finalTotal.add(total);
                                                        }

                                                    }
                                                }
                                                if ("4".equals(ryswModel4Data.getStructureType())) {
                                                    //其他
                                                    List<DataHouseQita> qitaList = dataHouseQitaService.getByGeom(ryswModel4Data.getIntersectGeom(), ryswModel4Data.getCode());
                                                    if (ObjectUtils.isNotEmpty(qitaList) && qitaList.size() > 0) {
                                                        BigDecimal area = qitaList.get(0).getHouse();
                                                        if(area.compareTo(BigDecimal.ZERO)==0){
                                                            finalTotal = finalTotal.add(BigDecimal.ZERO);
                                                        }else{
                                                            //获取钢混结构在这个烈度下的不同破坏程度的面积
                                                            //基本完好的
                                                            BigDecimal basicArea = ryswModel4Data.getBasic().multiply(area);
                                                            //轻微破坏的
                                                            BigDecimal slightArea = ryswModel4Data.getSlight().multiply(area);
                                                            //轻微破坏的
                                                            BigDecimal midArea = ryswModel4Data.getMid().multiply(area);
                                                            //轻微破坏的
                                                            BigDecimal seriousArea = ryswModel4Data.getSerious().multiply(area);
                                                            //轻微破坏的
                                                            BigDecimal destoryArea = ryswModel4Data.getDestory().multiply(area);
                                                            //total是多层砌体在某一烈度下的不同破坏程度下的建筑物结构经济损失
                                                            BigDecimal total = BigDecimal.ZERO;
                                                            //钢混 基本完好
                                                            BigDecimal basic = basicArea.multiply(BigDecimal.valueOf(matrixMap.get(ryswModel4Data.getStructureType()).getBasic()));
                                                            total = total.add(basic.multiply(BigDecimal.valueOf(price.getQitaRatio())));
                                                            //轻微破坏
                                                            BigDecimal slight = slightArea.multiply(BigDecimal.valueOf(matrixMap.get(ryswModel4Data.getStructureType()).getSlight()));
                                                            total = total.add(slight.multiply(BigDecimal.valueOf(price.getQitaRatio())));
                                                            //中等破坏
                                                            BigDecimal mid = midArea.multiply(BigDecimal.valueOf(matrixMap.get(ryswModel4Data.getStructureType()).getMid()));
                                                            total = total.add(mid.multiply(BigDecimal.valueOf(price.getQitaRatio())));
                                                            //严重破坏
                                                            BigDecimal serious = seriousArea.multiply(BigDecimal.valueOf(matrixMap.get(ryswModel4Data.getStructureType()).getSerious()));
                                                            total = total.add(serious.multiply(BigDecimal.valueOf(price.getQitaRatio())));
                                                            //毁坏
                                                            BigDecimal destory = destoryArea.multiply(BigDecimal.valueOf(matrixMap.get(ryswModel4Data.getStructureType()).getDestory()));
                                                            total = total.add(destory.multiply(BigDecimal.valueOf(price.getQitaRatio())));
                                                            finalTotal = finalTotal.add(total);
                                                        }

                                                    }
                                                }

                                            }
                                        }
                                    }
                                }
                            }
                            finalTotal = finalTotal.multiply(BigDecimal.valueOf(economyModel.getAdjustRatio())).divide(BigDecimal.valueOf(10000), 8, RoundingMode.HALF_DOWN);
                            EconomyEvaluate economyEvaluate = new EconomyEvaluate();
                            economyEvaluate.setId(UUID.randomUUID().toString().replace("-", ""))
                                    .setEarthQuakeId(earthQuakeId).setInfluenceVersion(influenceVersion).setIntensity(getIntensityMap().get(i )).setOperateTime(new Date());
                            economyEvaluate.setGeom(influence.getGeom()).setStructureLoss(finalTotal).setLifeLoss(BigDecimal.valueOf(economyModel.getLifeRatio()).multiply(finalTotal)).setOtherLoss(BigDecimal.valueOf(economyModel.getOtherRatio()).multiply(finalTotal));
                            resultList.add(economyEvaluate);
                        }
                        log.error("地震id" + earthQuakeId + "-- 评估经济损失" + "|| 成功。>> 参数:" + JSON.toJSONString(vo));
                        if (resultList.size() > 0) {
                            saveBatch(resultList);
                        }
                    }catch (Exception e){
                        e.printStackTrace();
                        String msgId = earthQuakeId;
                        int retryCount = retryMap.getOrDefault(msgId, 0);
                        log.error("{},--评估经济损失||失败,处理消息时发生错误:{},即将开始第{}次消息重试...",msgId,e.getMessage(),retryCount + 1, e);
                        if (retryCount >= failedRetry - 1) {
                            log.error("{},---评估经济损失||失败,消息将被拒绝，>>参数:{}",msgId,JSON.toJSONString(vo));
                            // 拒绝消息，并且不重新入队
                            try {
                                channel.basicReject(message.getMessageProperties().getDeliveryTag(), false);
                            } catch (IOException ex) {
                                ex.printStackTrace();
                            }
                            retryMap.remove(msgId);
                        } else {
                            // 重新发送消息到队列
                            try {
                                channel.basicPublish(message.getMessageProperties().getReceivedExchange(),
                                        message.getMessageProperties().getReceivedRoutingKey(),
                                        MessageProperties.MINIMAL_PERSISTENT_BASIC,
                                        JSON.toJSONBytes(vo));
                            } catch (IOException ex) {
                                ex.printStackTrace();
                            }
                            retryMap.put(msgId, retryCount + 1);
                            log.error("地震id"+earthQuakeId+"-- 评估经济损失"+"|| 失败。>> 参数:"+ JSON.toJSONString(vo));
                        }
                    }finally {
                        try {
                            channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                        MessageDataSourceSwitch.clearDataSource();
                        //发送消息给报告
                        sendMsgToReport(earthQuakeId,earthType,dataSourceKey,publish,influenceVersion);
                    }
                }
            }else{
                //发送消息给报告
                sendMsgToReport(earthQuakeId,earthType,dataSourceKey,publish,influenceVersion);
                MessageDataSourceSwitch.clearDataSource();
            }
        });
    }
    private void sendMsgToReport(String id,Integer earthQuakeType,String dataSourceKey,Boolean publish,String version)  {
        Map<String,Object> toReportMap = new HashMap<>();
        toReportMap.put("earthQuakeId",id);
        toReportMap.put("earthQuakeType",earthQuakeType);
        toReportMap.put("dataSourceKey",dataSourceKey);
        toReportMap.put("publish",publish);
        toReportMap.put("influenceVersion",version);
        //1 是自动触发生成的  2是手动重新计算的影响场
        toReportMap.put("influenceType","1");
        String status = "成功";
        try{
            rabbitTemplate.convertAndSend(QueueConfig.EXCHANGE_INFLUENCE,QueueConfig.KEY_INFLUENCE_TO_REPORT,toReportMap);
            log.error("地震id"+id+"-- 影响场给报告发送消息"+"|| 成功。>> 参数:"+JSON.toJSONString(toReportMap));
        }catch (Exception e){
            boolean flag = false;
            for (int i=0;i<failedRetry;i++) {
                try{
                    Thread.sleep(500);
                    rabbitTemplate.convertAndSend(QueueConfig.EXCHANGE_INFLUENCE,QueueConfig.KEY_INFLUENCE_TO_REPORT,toReportMap);
                    flag = true;
                    log.error("地震id"+id+"-- 影响场给报告发送消息"+"|| 成功。>> 参数:"+JSON.toJSONString(toReportMap));
                    break;
                }catch (Exception ignored){
                }
            }
            if(!flag){
                status = "失败";
                log.error("地震id"+id+"-- 影响场给报告发送消息"+"|| 失败。>> 参数:"+JSON.toJSONString(toReportMap));
            }
        }finally {
            try{
                LinkedHashMap<String, Object> content = JSON.parseObject(JSON.toJSONString(toReportMap), new TypeReference<LinkedHashMap<String, Object>>() {
                });
                messageLogService.createAndSaveMessageLog(QueueConfig.EXCHANGE_INFLUENCE,QueueConfig.KEY_INFLUENCE_TO_REPORT,status, content,"经济损失发送消息给报告","Map");
            }catch (Exception e){
                //消息发送情况的保存即使失败了也不能影响到影响场数据的保存 因为消息失败了也不会补偿发送所以偶尔保存失败也不会有很大的影响
                e.printStackTrace();
            }
        }
    }
    @Override
    @DSTransactional
    public void evaluation(String dataSourceKey, BigDecimal timeRatio, int maxIntensity, Map<String, SettingSeismicInfluenceflied> intensityMap, String earthQuakeId, DateTime influenceVersion,List<SettingSeismicInfluenceflied> influenceList) throws Exception{
        //先删除之前生成的相同影响场版本的数据
        LambdaQueryWrapper<EconomyEvaluate> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(EconomyEvaluate::getInfluenceVersion,influenceVersion).eq(EconomyEvaluate::getEarthQuakeId,earthQuakeId);
        remove(lambdaQueryWrapper);
        if(influenceList.size()>0 && influenceVersion!=null) {
            //获取经济损失模型
            EconomyModel economyModel = economyModelService.getOne(null);
            //获取建筑物损失比矩阵
            List<BuildingLossMatrix> matrixList = buildingLossMatrixService.list(null);
            Map<String, BuildingLossMatrix> matrixMap = matrixList.stream().collect(Collectors.toMap(BuildingLossMatrix::getStructureType, Function.identity()));
            List<EconomyEvaluate> resultList = new ArrayList<>();
            for(int i=6;i<=maxIntensity;i++) {
                BigDecimal finalTotal = BigDecimal.ZERO;
                SettingSeismicInfluenceflied influence  = intensityMap.get(i + "");
                if (ObjectUtils.isNotEmpty(influence)) {
                    //根据影响场烈度的空间数据查询易损性数据 模型数据使用的是震级所在的省的数据
                    List<RyswModel4Data> ryswModel4DataList = ryswModel4DataService.getIntersectYsx(influence.getGeom(), influence.getCode(), getIntensityMap().get(i));
                    if (ObjectUtils.isNotEmpty(ryswModel4DataList) && ryswModel4DataList.size() > 0) {
                        // 一个烈度圈可能与多个易损性数据相交7烈度的一半圈和一批易损性相交，另外半圈可能和另外的一批易损性数据相交
                        Map<String, List<RyswModel4Data>> pidMap = ryswModel4DataList.stream().collect(Collectors.groupingBy(RyswModel4Data::getIntersectGeom));
                        Iterator<Map.Entry<String, List<RyswModel4Data>>> iterator = pidMap.entrySet().iterator();
                        while (iterator.hasNext()) {
                            Map.Entry<String, List<RyswModel4Data>> next = iterator.next();
                            List<RyswModel4Data> v = next.getValue();
                            for (RyswModel4Data ryswModel4Data : v) {
                                //根据空间数据匹配建筑物造价数据
                                List<EconomyBuildingPrice> priceList = economyBuildingPriceService.getBuildingPriceByGeom(ryswModel4Data.getIntersectGeom());
                                for (EconomyBuildingPrice price : priceList) {
                                    if ("1".equals(ryswModel4Data.getStructureType())) {
                                        //钢混结构
                                        List<DataHouseRebar> rebarList = dataHouseRebarService.getByGeom(price.getGeomText(), "4490");
                                        if (ObjectUtils.isNotEmpty(rebarList) && rebarList.size() > 0) {
                                            BigDecimal area = rebarList.get(0).getHouse();
                                            if(area.compareTo(BigDecimal.ZERO)==0){
                                                finalTotal = finalTotal.add(BigDecimal.ZERO);
                                            }else{
                                                //获取钢混结构在这个烈度下的不同破坏程度的面积
                                                //基本完好的
                                                BigDecimal basicArea = ryswModel4Data.getBasic().multiply(area);
                                                //轻微破坏的
                                                BigDecimal slightArea = ryswModel4Data.getSlight().multiply(area);
                                                //轻微破坏的
                                                BigDecimal midArea = ryswModel4Data.getMid().multiply(area);
                                                //轻微破坏的
                                                BigDecimal seriousArea = ryswModel4Data.getSerious().multiply(area);
                                                //轻微破坏的
                                                BigDecimal destoryArea = ryswModel4Data.getDestory().multiply(area);
                                                //total是多层砌体在某一烈度下的不同破坏程度下的建筑物结构经济损失
                                                BigDecimal total = BigDecimal.ZERO;
                                                //钢混 基本完好
                                                BigDecimal basic = basicArea.multiply(BigDecimal.valueOf(matrixMap.get(ryswModel4Data.getStructureType()).getBasic()));
                                                total = total.add(basic.multiply(BigDecimal.valueOf(price.getGanghunRatio())));
                                                //轻微破坏
                                                BigDecimal slight = slightArea.multiply(BigDecimal.valueOf(matrixMap.get(ryswModel4Data.getStructureType()).getSlight()));
                                                total = total.add(slight.multiply(BigDecimal.valueOf(price.getGanghunRatio())));
                                                //中等破坏
                                                BigDecimal mid = midArea.multiply(BigDecimal.valueOf(matrixMap.get(ryswModel4Data.getStructureType()).getMid()));
                                                total = total.add(mid.multiply(BigDecimal.valueOf(price.getGanghunRatio())));
                                                //严重破坏
                                                BigDecimal serious = seriousArea.multiply(BigDecimal.valueOf(matrixMap.get(ryswModel4Data.getStructureType()).getSerious()));
                                                total = total.add(serious.multiply(BigDecimal.valueOf(price.getGanghunRatio())));
                                                //毁坏
                                                BigDecimal destory = destoryArea.multiply(BigDecimal.valueOf(matrixMap.get(ryswModel4Data.getStructureType()).getDestory()));
                                                total = total.add(destory.multiply(BigDecimal.valueOf(price.getGanghunRatio())));
                                                finalTotal = finalTotal.add(total);
                                            }

                                        }

                                    }
                                    if ("2".equals(ryswModel4Data.getStructureType())) {
                                        //多层砌体
                                        List<DataHouseBrickwork> bwList = dataHouseBrickworkService.getByGeom(ryswModel4Data.getIntersectGeom(), ryswModel4Data.getCode());
                                        if (ObjectUtils.isNotEmpty(bwList) && bwList.size() > 0) {
                                            BigDecimal area = bwList.get(0).getHouse();
                                            if(area.compareTo(BigDecimal.ZERO)==0){
                                                finalTotal = finalTotal.add(BigDecimal.ZERO);
                                            }else{
                                                //获取钢混结构在这个烈度下的不同破坏程度的面积
                                                //基本完好的
                                                BigDecimal basicArea = ryswModel4Data.getBasic().multiply(area);
                                                //轻微破坏的
                                                BigDecimal slightArea = ryswModel4Data.getSlight().multiply(area);
                                                //轻微破坏的
                                                BigDecimal midArea = ryswModel4Data.getMid().multiply(area);
                                                //轻微破坏的
                                                BigDecimal seriousArea = ryswModel4Data.getSerious().multiply(area);
                                                //轻微破坏的
                                                BigDecimal destoryArea = ryswModel4Data.getDestory().multiply(area);
                                                //total是多层砌体在某一烈度下的不同破坏程度下的建筑物结构经济损失
                                                BigDecimal total = BigDecimal.ZERO;
                                                //钢混 基本完好
                                                BigDecimal basic = basicArea.multiply(BigDecimal.valueOf(matrixMap.get(ryswModel4Data.getStructureType()).getBasic()));
                                                total = total.add(basic.multiply(BigDecimal.valueOf(price.getQitiRatio())));
                                                //轻微破坏
                                                BigDecimal slight = slightArea.multiply(BigDecimal.valueOf(matrixMap.get(ryswModel4Data.getStructureType()).getSlight()));
                                                total = total.add(slight.multiply(BigDecimal.valueOf(price.getQitiRatio())));
                                                //中等破坏
                                                BigDecimal mid = midArea.multiply(BigDecimal.valueOf(matrixMap.get(ryswModel4Data.getStructureType()).getMid()));
                                                total = total.add(mid.multiply(BigDecimal.valueOf(price.getQitiRatio())));
                                                //严重破坏
                                                BigDecimal serious = seriousArea.multiply(BigDecimal.valueOf(matrixMap.get(ryswModel4Data.getStructureType()).getSerious()));
                                                total = total.add(serious.multiply(BigDecimal.valueOf(price.getQitiRatio())));
                                                //毁坏
                                                BigDecimal destory = destoryArea.multiply(BigDecimal.valueOf(matrixMap.get(ryswModel4Data.getStructureType()).getDestory()));
                                                total = total.add(destory.multiply(BigDecimal.valueOf(price.getQitiRatio())));
                                                finalTotal = finalTotal.add(total);
                                            }

                                        }
                                    }
                                    if ("3".equals(ryswModel4Data.getStructureType())) {
                                        //单层
                                        List<DataHousedanceng> dancengList = dataHouseDancengService.getByGeom(ryswModel4Data.getIntersectGeom(), ryswModel4Data.getCode());
                                        if (ObjectUtils.isNotEmpty(dancengList) && dancengList.size() > 0) {
                                            BigDecimal area = dancengList.get(0).getHouse();
                                            if(area.compareTo(BigDecimal.ZERO)==0){
                                                finalTotal = finalTotal.add(BigDecimal.ZERO);
                                            }else{
                                                //获取钢混结构在这个烈度下的不同破坏程度的面积
                                                //基本完好的
                                                BigDecimal basicArea = ryswModel4Data.getBasic().multiply(area);
                                                //轻微破坏的
                                                BigDecimal slightArea = ryswModel4Data.getSlight().multiply(area);
                                                //轻微破坏的
                                                BigDecimal midArea = ryswModel4Data.getMid().multiply(area);
                                                //轻微破坏的
                                                BigDecimal seriousArea = ryswModel4Data.getSerious().multiply(area);
                                                //轻微破坏的
                                                BigDecimal destoryArea = ryswModel4Data.getDestory().multiply(area);
                                                //total是多层砌体在某一烈度下的不同破坏程度下的建筑物结构经济损失
                                                BigDecimal total = BigDecimal.ZERO;
                                                //钢混 基本完好
                                                BigDecimal basic = basicArea.multiply(BigDecimal.valueOf(matrixMap.get(ryswModel4Data.getStructureType()).getBasic()));
                                                total = total.add(basic.multiply(BigDecimal.valueOf(price.getDangcengRatio())));
                                                //轻微破坏
                                                BigDecimal slight = slightArea.multiply(BigDecimal.valueOf(matrixMap.get(ryswModel4Data.getStructureType()).getSlight()));
                                                total = total.add(slight.multiply(BigDecimal.valueOf(price.getDangcengRatio())));
                                                //中等破坏
                                                BigDecimal mid = midArea.multiply(BigDecimal.valueOf(matrixMap.get(ryswModel4Data.getStructureType()).getMid()));
                                                total = total.add(mid.multiply(BigDecimal.valueOf(price.getDangcengRatio())));
                                                //严重破坏
                                                BigDecimal serious = seriousArea.multiply(BigDecimal.valueOf(matrixMap.get(ryswModel4Data.getStructureType()).getSerious()));
                                                total = total.add(serious.multiply(BigDecimal.valueOf(price.getDangcengRatio())));
                                                //毁坏
                                                BigDecimal destory = destoryArea.multiply(BigDecimal.valueOf(matrixMap.get(ryswModel4Data.getStructureType()).getDestory()));
                                                total = total.add(destory.multiply(BigDecimal.valueOf(price.getDangcengRatio())));
                                                finalTotal = finalTotal.add(total);
                                            }

                                        }
                                    }
                                    if ("4".equals(ryswModel4Data.getStructureType())) {
                                        //其他
                                        List<DataHouseQita> qitaList = dataHouseQitaService.getByGeom(ryswModel4Data.getIntersectGeom(), ryswModel4Data.getCode());
                                        if (ObjectUtils.isNotEmpty(qitaList) && qitaList.size() > 0) {
                                            BigDecimal area = qitaList.get(0).getHouse();
                                            if(area.compareTo(BigDecimal.ZERO)==0){
                                                finalTotal = finalTotal.add(BigDecimal.ZERO);
                                            }else{
                                                //获取钢混结构在这个烈度下的不同破坏程度的面积
                                                //基本完好的
                                                BigDecimal basicArea = ryswModel4Data.getBasic().multiply(area);
                                                //轻微破坏的
                                                BigDecimal slightArea = ryswModel4Data.getSlight().multiply(area);
                                                //轻微破坏的
                                                BigDecimal midArea = ryswModel4Data.getMid().multiply(area);
                                                //轻微破坏的
                                                BigDecimal seriousArea = ryswModel4Data.getSerious().multiply(area);
                                                //轻微破坏的
                                                BigDecimal destoryArea = ryswModel4Data.getDestory().multiply(area);
                                                //total是多层砌体在某一烈度下的不同破坏程度下的建筑物结构经济损失
                                                BigDecimal total = BigDecimal.ZERO;
                                                //钢混 基本完好
                                                BigDecimal basic = basicArea.multiply(BigDecimal.valueOf(matrixMap.get(ryswModel4Data.getStructureType()).getBasic()));
                                                total = total.add(basic.multiply(BigDecimal.valueOf(price.getQitaRatio())));
                                                //轻微破坏
                                                BigDecimal slight = slightArea.multiply(BigDecimal.valueOf(matrixMap.get(ryswModel4Data.getStructureType()).getSlight()));
                                                total = total.add(slight.multiply(BigDecimal.valueOf(price.getQitaRatio())));
                                                //中等破坏
                                                BigDecimal mid = midArea.multiply(BigDecimal.valueOf(matrixMap.get(ryswModel4Data.getStructureType()).getMid()));
                                                total = total.add(mid.multiply(BigDecimal.valueOf(price.getQitaRatio())));
                                                //严重破坏
                                                BigDecimal serious = seriousArea.multiply(BigDecimal.valueOf(matrixMap.get(ryswModel4Data.getStructureType()).getSerious()));
                                                total = total.add(serious.multiply(BigDecimal.valueOf(price.getQitaRatio())));
                                                //毁坏
                                                BigDecimal destory = destoryArea.multiply(BigDecimal.valueOf(matrixMap.get(ryswModel4Data.getStructureType()).getDestory()));
                                                total = total.add(destory.multiply(BigDecimal.valueOf(price.getQitaRatio())));
                                                finalTotal = finalTotal.add(total);
                                            }

                                        }
                                    }
                                }
                                finalTotal = finalTotal.multiply(BigDecimal.valueOf(economyModel.getAdjustRatio())).divide(BigDecimal.valueOf(10000), 8, RoundingMode.HALF_DOWN);
                            }
                        }
                    }
                }
                EconomyEvaluate economyEvaluate = new EconomyEvaluate();
                economyEvaluate.setId(UUID.randomUUID().toString().replace("-", ""))
                        .setEarthQuakeId(earthQuakeId).setInfluenceVersion(formatDate(influenceVersion.toString())).setIntensity(getIntensityMap().get(i )).setOperateTime(new Date());
                economyEvaluate.setGeom(influence.getGeom()).setStructureLoss(finalTotal).setLifeLoss(BigDecimal.valueOf(economyModel.getLifeRatio()).multiply(finalTotal)).setOtherLoss(BigDecimal.valueOf(economyModel.getOtherRatio()).multiply(finalTotal));
                resultList.add(economyEvaluate);

            }
            if (resultList.size() > 0) {
                saveBatch(resultList);
                log.error("地震id"+earthQuakeId+"-- 评估经济损失"+"|| 成功。");
            }else{
                log.error("地震id"+earthQuakeId+"-- 评估经济损失"+"|| 成功。但未生成任何结果数据");
            }
        }
    }

    @DSTransactional
    public void evaluationBak(String earthQuakeId,String influenceVersion) throws Exception{
        //先删除之前生成的相同影响场版本的数据
        LambdaQueryWrapper<EconomyEvaluate> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(EconomyEvaluate::getInfluenceVersion,influenceVersion).eq(EconomyEvaluate::getEarthQuakeId,earthQuakeId);
        remove(lambdaQueryWrapper);
        //获取人员伤亡模型3计算时得到的每个结构类型各烈度下不同破坏程度的建筑物面积
        List<GridDestoryDetails> list = gridDestoryDetailsService.getAll(earthQuakeId,influenceVersion);
        if(ObjectUtils.isNotEmpty(list) && list.size()>0){
            //获取经济损失模型
            EconomyModel economyModel = economyModelService.getOne(null);
            //获取建筑物损失比矩阵
            List<BuildingLossMatrix> matrixList = buildingLossMatrixService.list(null);
            Map<String, BuildingLossMatrix> matrixMap = matrixList.stream().collect(Collectors.toMap(BuildingLossMatrix::getStructureType, Function.identity()));
            Map<String,List<EconomyBuildingPrice>> priceMap = new HashMap<>();
            //key是烈度 v是该烈度下的建筑物经济损失
            Table<String,String,BigDecimal> intensityTable = HashBasedTable.create();
            /**
             * 建筑物经济损失 = 各烈度不同类建筑物在不同破坏等级下的破坏面积*建筑物每平方米造价*不同类建筑物在不同破坏等级下的损失比*评估调整参数/10000 之和
             */
            for (GridDestoryDetails gridDestoryDetails : list) {
                //获取建筑物造价数据
                List<EconomyBuildingPrice> priceList = null;
                if(!priceMap.containsKey(gridDestoryDetails.getGeom())){
                    //根据空间数据匹配建筑物造价数据
                    priceList = economyBuildingPriceService.getBuildingPriceByGeom(gridDestoryDetails.getGeomText());
                    priceMap.put(gridDestoryDetails.getGeom(),priceList);
                }else{
                    priceList = priceMap.get(gridDestoryDetails.getGeom());
                }
                EconomyBuildingPrice price = null;
                if(priceList.size()>0){
                    price = priceList.get(0);
                }
                if(price == null){
                    continue;
                }
                String structureType = gridDestoryDetails.getStructureType();
                BigDecimal total = BigDecimal.ZERO;
                if("1".equals(structureType)){
                    //total是钢混结构在某一烈度下的不同破坏程度下的建筑物结构经济损失
                    total = getStructureLoss(gridDestoryDetails,matrixMap,structureType,BigDecimal.valueOf(price.getGanghunRatio()));
                }else  if("2".equals(structureType)){
                    //total是多层砌体在某一烈度下的不同破坏程度下的建筑物结构经济损失
                    total = getStructureLoss(gridDestoryDetails,matrixMap,structureType,BigDecimal.valueOf(price.getQitiRatio()));
                }else  if("3".equals(structureType)){
                    //total是单层在某一烈度下的不同破坏程度下的建筑物结构经济损失
                    total = getStructureLoss(gridDestoryDetails,matrixMap,structureType,BigDecimal.valueOf(price.getDangcengRatio()));
                }else  if("4".equals(structureType)){
                    //total是其他结构在某一烈度下的不同破坏程度下的建筑物结构经济损失
                    total = getStructureLoss(gridDestoryDetails,matrixMap,structureType,BigDecimal.valueOf(price.getQitaRatio()));
                }
                total = total.multiply(BigDecimal.valueOf(economyModel.getAdjustRatio())).divide(BigDecimal.valueOf(10000),8, RoundingMode.HALF_DOWN);
//                if(intensityTable.containsRow(gridDestoryDetails.getIntensity())){
//                    BigDecimal val = intensityTable.get(gridDestoryDetails.getIntensity(),gridDestoryDetails.getGeom());
//                    val = val.add(total);
//                    intensityTable.put(gridDestoryDetails.getIntensity(),gridDestoryDetails.getGeom(),val);
//                }else{
//                    intensityTable.put(gridDestoryDetails.getIntensity(),gridDestoryDetails.getGeom(),total);
//                }
                if(intensityTable.contains(gridDestoryDetails.getIntensity(),gridDestoryDetails.getGeom())){
                    BigDecimal val ;
                    try{
                        val = intensityTable.get(gridDestoryDetails.getIntensity(),gridDestoryDetails.getGeom());
                        val = val.add(total);
                        intensityTable.put(gridDestoryDetails.getIntensity(),gridDestoryDetails.getGeom(),val);
                    }catch (Exception e){
                        e.printStackTrace();
                    }
                }else{
                    intensityTable.put(gridDestoryDetails.getIntensity(),gridDestoryDetails.getGeom(),total);
                }
            }
            List<EconomyEvaluate> resultList = new ArrayList<>();
            intensityTable.rowMap().forEach((k,v)->{
                //k是烈度  <烈度的空间数据，建筑物经济损失>
                EconomyEvaluate economyEvaluate = new EconomyEvaluate();
                economyEvaluate.setId(UUID.randomUUID().toString().replace("-",""))
                        .setEarthQuakeId(earthQuakeId).setInfluenceVersion(influenceVersion).setIntensity(k).setOperateTime(new Date());
                v.forEach((k1,v1)->{
                    economyEvaluate.setGeom(k1).setStructureLoss(v1).setLifeLoss(BigDecimal.valueOf(economyModel.getLifeRatio()).multiply(v1)).setOtherLoss(BigDecimal.valueOf(economyModel.getOtherRatio()).multiply(v1));
                });
                resultList.add(economyEvaluate);
            });
            log.error("地震id"+earthQuakeId+"-- 评估经济损失"+"|| 成功。");
            if(resultList.size()>0){
                saveBatch(resultList);
                try{
                    //删除人员伤亡处保存的给计算经济损失使用的中间数据
                    LambdaQueryWrapper<GridDestoryDetails> removeLam = new LambdaQueryWrapper();
                    removeLam.eq(GridDestoryDetails::getEarthQuakeId,earthQuakeId).eq(GridDestoryDetails::getInfluenceVersion,influenceVersion);
                    gridDestoryDetailsService.remove(removeLam);
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 获取某一结构类型在某一烈度下不同破坏程度的经济损失之和
     */
    private BigDecimal getStructureLoss(GridDestoryDetails gridDestoryDetails,Map<String, BuildingLossMatrix> matrixMap,String structureType,BigDecimal price){
        //total是多层砌体在某一烈度下的不同破坏程度下的建筑物结构经济损失
        BigDecimal total = BigDecimal.ZERO;
        //钢混 基本完好
        BigDecimal basic = gridDestoryDetails.getBasicArea().multiply(BigDecimal.valueOf(matrixMap.get(structureType).getBasic()));
        total = total.add(basic);
        //轻微破坏
        BigDecimal slight = gridDestoryDetails.getSlightArea().multiply(BigDecimal.valueOf(matrixMap.get(structureType).getSlight()));
        total = total.add(slight);
        //中等破坏
        BigDecimal mid = gridDestoryDetails.getMidArea().multiply(BigDecimal.valueOf(matrixMap.get(structureType).getMid()));
        total = total.add(mid);
        //严重破坏
        BigDecimal serious = gridDestoryDetails.getSeriousArea().multiply(BigDecimal.valueOf(matrixMap.get(structureType).getSerious()));
        total = total.add(serious);
        //毁坏
        BigDecimal destory = gridDestoryDetails.getDestoryArea().multiply(BigDecimal.valueOf(matrixMap.get(structureType).getDestory()));
        total = total.add(destory);
        return total.multiply(price);
    }
}
